/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sv.gob.mh.dgii.ssc.ruc.controller;

import com.google.common.collect.Sets;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.SpelEvaluationException;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttributes;
import sv.gob.mh.dgii.common.PagedResult;
import sv.gob.mh.dgii.dao.de.modulos.dinamico.QueryDeRucPerfil;
import sv.gob.mh.dgii.dao.ruc.QueryRcCaractTrib;
import sv.gob.mh.dgii.dao.ruc.QueryRucDao;
import sv.gob.mh.dgii.html.editor.SiitDateEditor;
import sv.gob.mh.dgii.model.DeRucOpcionMsj;
import sv.gob.mh.dgii.model.DeRucPerOpcCam;
import sv.gob.mh.dgii.model.DeRucPerfil;
import sv.gob.mh.dgii.model.DeRucPerfilOpc;
import sv.gob.mh.dgii.model.RcActEco;
import sv.gob.mh.dgii.model.RcActEcoTmp;
import sv.gob.mh.dgii.model.RcCaractTrib;
import sv.gob.mh.dgii.model.RcDomicilio;
import sv.gob.mh.dgii.model.RcRepresentante;
import sv.gob.mh.dgii.model.RcRuc;
import sv.gob.mh.dgii.model.RcRucTmp;
import sv.gob.mh.dgii.model.RcRucTmpId;
import sv.gob.mh.dgii.model.RcSocio;
import sv.gob.mh.dgii.model.RcSocioId;
import sv.gob.mh.dgii.model.TbActEco;
import sv.gob.mh.dgii.model.pojos.menu.MensajeDinamico;
import sv.gob.mh.dgii.model.pojos.ruc.CampoOpcion;
import sv.gob.mh.dgii.model.pojos.ruc.OpcionContribuyente;
import sv.gob.mh.dgii.service.cat.ActividadEconomicaService;
import sv.gob.mh.dgii.service.cat.DepartamentoService;
import sv.gob.mh.dgii.service.cat.DocIdentidadService;
import sv.gob.mh.dgii.service.cat.MunicipioService;
import sv.gob.mh.dgii.service.cat.PaisService;
import sv.gob.mh.dgii.service.cat.TbRepresentanteService;
import sv.gob.mh.dgii.service.rc.RcActEcoService;
import sv.gob.mh.dgii.service.rc.RcDomicilioService;
import sv.gob.mh.dgii.service.rc.RcDomicilioTmpService;
import sv.gob.mh.dgii.service.rc.RcRepresentanteService;
import sv.gob.mh.dgii.service.rc.RcRepresentanteTmpService;
import sv.gob.mh.dgii.service.rc.RcRucService;
import sv.gob.mh.dgii.service.rc.RcRucTmpService;
import sv.gob.mh.dgii.service.rc.RcSocioService;
import sv.gob.mh.dgii.service.rc.RcTramiteTmpService;
import sv.gob.mh.dgii.ssc.controller.configuration.HomeController;
import sv.gob.mh.dgii.ssc.ruc.form.ActualizarRucForm;

/**
 *
 * @author Hacienda
 */
@Controller
@RequestMapping(value = "/servicios/registro/ruc")
@SessionAttributes({"actualizarRucForm"})
public class ActualizarRucController {

    private final static Log log = LogFactory.getLog(ActualizarRucController.class);
    private final static String PREFIX = "ruc/";
    private final String NRC = "NRC";
    private final String MODULO_CONTRIBUYENTE = "ACTUALIZACION_CONTRIBUYENTE";
    @Autowired
    private QueryRucDao queryRucDao;
    @Autowired
    private RcRucTmpService rcRucTmpService;
    @Autowired
    private RcRucService rcRucService;
    @Autowired
    private MunicipioService municipioService;
    @Autowired
    private DepartamentoService departamentoService;
    @Autowired
    private PaisService paisService;
    @Autowired
    private ActividadEconomicaService actividadEconomicaService;
    @Autowired
    private DocIdentidadService DocIdentidadService;
    @Autowired
    private QueryRcCaractTrib queryRcCaractTrib;
    @Autowired
    private TbRepresentanteService tbRepresentanteService;
    @Autowired
    private QueryDeRucPerfil queryDeRucPerfil;
    @Autowired
    private RcDomicilioService rcDomicilioService;
    @Autowired
    private RcSocioService rcSocioService;
    @Autowired
    private RcRepresentanteService rcRepresentanteService;
    @Autowired
    private RcTramiteTmpService rcTramiteTmpService;
    @Autowired
    private RcActEcoService rcActEcoService;
    HomeController usuario;
    String user;
    

    /**
     * Dibuja las opciones del perfil relacionado al Contribuyente que esta en sessión.
     */
    @RequestMapping(value = "/menu")
    public String menu(Model model) {
        
        //Se obtiene el contexto del bean generico en session
        ActualizarRucForm actualizarRucForm = (ActualizarRucForm) model.asMap().get("actualizarRucForm");
        
        
        if(actualizarRucForm==null)
            actualizarRucForm = new ActualizarRucForm();
        
        DeRucPerfil perfil = null;
        boolean inscritoIva = false;
        String claseContribuyente = "";
        if(actualizarRucForm.getContribuyente()==null){
        //Cargando información del contribuyente RC_RUC
            RcRuc rcRuc = buscarContribuyentePorNitUsuario();
            if(rcRuc!=null){
                //Evaluación de inscripción al IVA
                RcCaractTrib caracterTributario;
                try{
                    caracterTributario = queryRcCaractTrib.obtenerCaracterTributarioPorNIT(rcRuc.getNit());
                }catch(java.lang.NullPointerException e){
                    caracterTributario = null;
                }
                if(caracterTributario!=null && caracterTributario.getId().getCcaractTrib().equals(NRC))
                    inscritoIva = true;
                claseContribuyente = rcRuc.getTbTipoContrib().getTbClaseContrib().getCclase();


                actualizarRucForm.setContribuyente(rcRuc);
                actualizarRucForm.setContribuyenteTmp(new RcRucTmp());
            }
            //Cargando de la plataforma de parametrización de modulos el Perfil asociados al modulo RUC
            String condicionPerfil = transformarCondicionPerfil(claseContribuyente, inscritoIva);
            perfil =  queryDeRucPerfil.obtenerPerfilPorModuloDinamico(MODULO_CONTRIBUYENTE, condicionPerfil);
            actualizarRucForm.setPerfilContribuyente(perfil);

            //Cargando las opciones de la plataforma de parametrización de modulos en relación al perfil del contribuyente
            List<OpcionContribuyente> listaOpcionesContribuyente = generarOpcionesContribuyente(perfil, actualizarRucForm);
            actualizarRucForm.setOpcionesContribuyente(listaOpcionesContribuyente);
        
        }
        
          
        actualizarRucForm.setCamposCargados(false);
        model.addAttribute("actualizarRucForm", actualizarRucForm);
        return PREFIX + "menu";
    }
   

    
    @RequestMapping(value = "/requisitos/{v}")
    public String requisitos(@PathVariable String v, Model model) {
        
        //Se obtiene el contexto del bean generico en session
        ActualizarRucForm actualizarRucForm = (ActualizarRucForm) model.asMap().get("actualizarRucForm");
        
        //Evalua la petición 
        if(Integer.parseInt(v)!=0){
                OpcionContribuyente opcionSeleccionada = new OpcionContribuyente();
                opcionSeleccionada = opcionSeleccionada.buscarPorId(actualizarRucForm.getOpcionesContribuyente(), Integer.parseInt(v));
                actualizarRucForm.setOpcionSeleccionada(opcionSeleccionada);

                cargarCatalogos(actualizarRucForm);
                
                
        }
        
        model.addAttribute("actualizarRucForm", actualizarRucForm);
        //List<OpcionContribuyente> opcionesDependiente = obtenerOpcionesSubMenu(opcionSeleccionada); ////CONTINUAR
        return PREFIX + "requisitosruc";
    }
    
    @RequestMapping(value = "/formulario")    
    public String form(Model model){
        ActualizarRucForm actualizarRucForm = (ActualizarRucForm) model.asMap().get("actualizarRucForm");
        actualizarRucForm.getContribuyente().setRcDomicilios(new TreeSet<RcDomicilio>());
        actualizarRucForm.getContribuyente().setRcSociosForNit(new TreeSet<RcSocio>());
        actualizarRucForm.getContribuyente().setRcRepresentantesForNit(new TreeSet<RcRepresentante>());
        
        if(!actualizarRucForm.isCamposCargados()){
            for(OpcionContribuyente opcion : actualizarRucForm.getOpcionesContribuyente()){
                
                //Si la opción es del menu principal o es una predecesora no se evaluara para obtener campos
                if(opcion.getIdentificador()==1 || opcion.getPredecesor()==1)
                    continue;
                
                    //Obteniendo los campos en base al perfil y a la opción evaluada
                    List<DeRucPerOpcCam> camposPorPerfil = queryDeRucPerfil.obtenerCamposPorPerfil(actualizarRucForm.getPerfilContribuyente().getIdPerfil().intValue(),opcion.getIdentificador());
                    //Ingresando la lista de campos
                    opcion.setCampos(new ArrayList<CampoOpcion>());
                    for(DeRucPerOpcCam deRucPerOpcCam : camposPorPerfil){
                            ExpressionParser parser = new SpelExpressionParser();
                            StandardEvaluationContext context = new StandardEvaluationContext(actualizarRucForm);
                            String valorCampo = "";
                            try{
                                valorCampo=parser.parseExpression(deRucPerOpcCam.getDeRucCampo().getTablaAsociada()).getValue(context, String.class);
                            }catch(SpelEvaluationException ne){
                                //Campos nulos se oviaran
                                valorCampo = "";   
                            }
                            CampoOpcion campoOpcion = new CampoOpcion();
                            campoOpcion.setValor(valorCampo);
                            campoOpcion.setIdentificador(deRucPerOpcCam.getDeRucCampo().getIdCampo().intValue());
                            campoOpcion.setNombre(deRucPerOpcCam.getEtiqueta());
                            campoOpcion.setPath(deRucPerOpcCam.getDeRucCampo().getCampoAsociado());
                            campoOpcion.setTipoCampo(deRucPerOpcCam.getDeRucCampo().getIdTipoCampo().getNombre());
                            campoOpcion.setTipoDato(deRucPerOpcCam.getDeRucCampo().getIdTipoDato().getNombre());
                            campoOpcion.setEditable(deRucPerOpcCam.getEditable());
                            campoOpcion.setValoresPosibles(parser.parseExpression(deRucPerOpcCam.getDeRucCampo().getValoresPosibles()).getValue(context, List.class));
                            campoOpcion.setValorEtiqueta(deRucPerOpcCam.getDeRucCampo().getValorEtiqueta());
                            campoOpcion.setValorAlmacenar(deRucPerOpcCam.getDeRucCampo().getValorAlmacenar());
                            campoOpcion.setLongitud(deRucPerOpcCam.getDeRucCampo().getLongitud().intValue());
                            campoOpcion.setPrecision(deRucPerOpcCam.getDeRucCampo().getPrecision().intValue());
                            opcion.getCampos().add(campoOpcion);
                    }

            }
            actualizarRucForm.setCamposCargados(true);
        }
        
        model.addAttribute("actualizarRucForm", actualizarRucForm);
        return PREFIX + "formulario";
    } 
    
    
    @RequestMapping(value = "/cargarFormulario", method = RequestMethod.POST)
    public @ResponseBody String cargarFormulario( Model model, @ModelAttribute("cargarOpcion") String valor) {
        
        ActualizarRucForm actualizarRucForm = (ActualizarRucForm) model.asMap().get("actualizarRucForm");

        for(OpcionContribuyente opcion : actualizarRucForm.getOpcionesContribuyente()){
            if(opcion.getIdentificador() == Integer.parseInt(valor)){
                if(opcion.getNombre().toLowerCase().contains("omicilio") || opcion.getNombre().contains("ucursal")|| opcion.getNombre().contains("matriz")){
                    System.out.println("Domicilios obtenidos de la BD : " + rcDomicilioService.obtenerDomicilios(actualizarRucForm.getContribuyente().getNit()).size());
                    actualizarRucForm.getContribuyente().setRcDomicilios(Sets.newHashSet(rcDomicilioService.obtenerDomicilios(actualizarRucForm.getContribuyente().getNit())));
                    System.out.println("Numero de domicilios : " + actualizarRucForm.getContribuyente().getRcDomicilios().size());
                }
                if(opcion.getNombre().toLowerCase().contains("socio")){
                    actualizarRucForm.getContribuyente().setRcSociosForNit(Sets.newHashSet(rcSocioService.obtenerSocios(actualizarRucForm.getContribuyente().getNit())));
                }
                if(opcion.getNombre().toLowerCase().contains("representan")){
                    actualizarRucForm.getContribuyente().setRcRepresentantesForNit(Sets.newHashSet(rcRepresentanteService.obtenerRepresentantesPorNit(actualizarRucForm.getContribuyente().getNit())));
                }
                
            }
        }


        model.addAttribute("actualizarRucForm", actualizarRucForm);
        return "0";
    }
    
    

    @RequestMapping(value = "/save", method = RequestMethod.PUT)
    public String save(Model model, @ModelAttribute(value = "actualizarRucForm") ActualizarRucForm actualizarRucForm) {
        usuario = new HomeController();
        System.out.println("Ingresando a la evaluación RUC");
        if (actualizarRucForm != null) {
            System.out.println("Ingresando a almacenar el RUC");
            long count = rcRucTmpService.getAllCount().longValue();
            System.out.println("Contador de registros : " + count);
            RcRucTmpId rcRucTmpId = new RcRucTmpId(count + 1, usuario.getPrincipal().getNit());
            actualizarRucForm.getContribuyenteTmp().setId(rcRucTmpId);
            
            List<RcActEcoTmp> actividadesEconomicas = new ArrayList<RcActEcoTmp>();
            /*
            for(RcActEco actividad : actualizarRucForm.getContribuyente().getRcActEcos()){
                RcActEcoTmp actividadTmp = new RcActEcoTmp();
                actividadTmp.setCUsuario(actividad.getCusuario());
                actividadTmp.setFfActEco(actividad.getFfactEco());
                actividadTmp.setFiActEco(actividad.getFiactEco());
                actividadTmp.setIRcActEco(rcActEcoTmpService.getAllCount().longValue());
            }*/
            
            /*
            RcRepresentanteTmp rcRepresentanteTmp = new RcRepresentanteTmp();
            RcRepresentanteTmpId rcRepresentanteTmpId = new RcRepresentanteTmpId();

            rcRepresentanteTmpId.setICorrelativo(51);
            rcRepresentanteTmpId.setNit(user);
            rcRepresentanteTmpId.setCRepresentante("1");
            rcRepresentanteTmp.setId(rcRepresentanteTmpId);
            rcRepresentanteTmpService.save(rcRepresentanteTmp);
*/
            try{
                rcRucTmpService.save(actualizarRucForm.getContribuyenteTmp());
            }catch(Exception e){
                System.out.println("Excepcion al guardar RUC " + e.getMessage());
                e.printStackTrace();
            }
                
            
        }
        return "redirect:/servicios/registro/ruc/menu";
    }

    
    @InitBinder
    protected void initBinder(HttpServletRequest request,
            ServletRequestDataBinder binder) throws Exception {
        binder.registerCustomEditor(Date.class, new SiitDateEditor());
    }

    /**
     * Genera la condición a evaluar para la busqueda del perfil dinamico
     * @param claseContribuyente el tipo de contribuyente
     * @param inscritoIVA recibe si el contribuyente evaluado es inscrito a IVA
     * @return Retorna un solo codigo de cuatro caracteres dependiendo las variables ingresadas
     */
    private String transformarCondicionPerfil(String claseContribuyente, boolean inscritoIVA) {
        //Cargara mensajes de error de aplicación.
        if(claseContribuyente.length()==0){
            return "9999";
        }
        StringBuilder codigo = new StringBuilder();
        if(claseContribuyente.equals("N"))  //Tipo contribuyente Natural
            codigo.append("01");
        else
            codigo.append("02");            //Tipo de contribuyente Juridico
        if(inscritoIVA)
            codigo.append("01");            //Inscrito IVA
        else
            codigo.append("02");            //No inscrito IVA
        return codigo.toString();
    }

    
    
    /**
     * Genera las opciones en base a la plataforma de parametrización de modulos
     * en base a un perfil asignado
     * @param perfil Perfil que esta ligado un contribuyente
     * @return Lista de opciones de contribuyente
     */
    private List<OpcionContribuyente> generarOpcionesContribuyente(DeRucPerfil perfil, ActualizarRucForm actualizarRucForm) {
        List<OpcionContribuyente> opcionesContribuyentes = new ArrayList<OpcionContribuyente>();
        List<DeRucPerfilOpc> listaDeRucPerfilOpcs = obtenerListaOpcionesPerfil(perfil);
        for(DeRucPerfilOpc perfilOpcion : listaDeRucPerfilOpcs){
            //Gestionamos las opciones del menu Principal
            if(perfilOpcion.getDeRucOpcion().getNombre().contains("PRINCIPAL")){
                actualizarRucForm.setMensajesMenuPrincipal(obtenerMensajesOpcion(perfilOpcion));
            }else{
                
                //Se cargan las opciones con sus respectivos mensajes de parametrización
                opcionesContribuyentes.add(new OpcionContribuyente(perfilOpcion.getDeRucOpcion().getIdOpcion().intValue(), 
                                                                   perfilOpcion.getDeRucOpcion().getIdOpcionPrincipal().intValue(),
                                                                   perfilOpcion.getDeRucOpcion().getNombre(), 
                                                                   perfilOpcion.getDeRucOpcion().getAccion(),
                                                                   obtenerMensajesOpcion(perfilOpcion)));
            }
        }
        return opcionesContribuyentes;
    }
    
    
    
    /**
     * Obtiene los mensajes relacionados a una opción de
     * la plataforma de parametrización de modulos
     * @param perfilOpcion Perfil con opcion 
     * @return Lista de mensajes dinamicos relacionados con perfilOpcion
     */
     private List<MensajeDinamico> obtenerMensajesOpcion(DeRucPerfilOpc perfilOpcion) {
         List<MensajeDinamico> mensajes = new ArrayList<MensajeDinamico>();
         List<DeRucOpcionMsj> listaDeRucOpcionMsjs = obtenerListaMensajesPerfilOpcion(perfilOpcion);
         for(DeRucOpcionMsj mensaje : listaDeRucOpcionMsjs){
             mensajes.add(new MensajeDinamico(mensaje.getValor(), mensaje.getEstiloPosicion(), mensaje.getIdTipoMensaje().getNombre()));
         }
        return mensajes;
    }
    
    
    
    /**
     * Obtiene la lista de opciones que tiene acceso un perfil
     * @param perfil Perfil que esta ligado por condicion un contribuyente
     * @return Lista de Perfiles Opciones
     */
    private List<DeRucPerfilOpc> obtenerListaOpcionesPerfil(DeRucPerfil perfil){
        return queryDeRucPerfil.obtenerOpcionesPerfil(perfil.getIdPerfil());
    }
    
    
     /**
     * Obtiene la lista de Mensajes por opcion
     * @param perfilOpcion Perfil y opción que esta ligado un mensaje
     * @return Lista de Mensajes a  Opciones
     */
    private List<DeRucOpcionMsj> obtenerListaMensajesPerfilOpcion(DeRucPerfilOpc perfilOpcion) {
        return queryDeRucPerfil.obtenerMensajesPorPerfilOpcion(perfilOpcion);
    }

    
    /**
     * Carga todos los catalogos correspondientes a un perfil
     */
    private void cargarCatalogos(ActualizarRucForm actualizarRucForm) {
        if(actualizarRucForm.getDepartamentos()==null || actualizarRucForm.getDepartamentos().isEmpty())
            actualizarRucForm.setDepartamentos(departamentoService.findAll());
        if(actualizarRucForm.getMunicipios()==null || actualizarRucForm.getMunicipios().isEmpty())
            actualizarRucForm.setMunicipios(municipioService.findAll());
        if(actualizarRucForm.getPais()==null || actualizarRucForm.getPais().isEmpty())
            actualizarRucForm.setPais(paisService.findAll());
        if(actualizarRucForm.getActEco()==null || actualizarRucForm.getActEco().isEmpty())
            actualizarRucForm.setActEco(actividadEconomicaService.findAll());
        if(actualizarRucForm.getRepresentantes()==null || actualizarRucForm.getRepresentantes().isEmpty())
            actualizarRucForm.setRepresentantes(tbRepresentanteService.findAll());
        if(actualizarRucForm.getDocIden()==null || actualizarRucForm.getDocIden().isEmpty())
            actualizarRucForm.setDocIden(DocIdentidadService.findAll());
        
        actualizarRucForm.getContribuyenteTmp().setCPais(actualizarRucForm.getContribuyente().getTbPais().getCpais());
        actualizarRucForm.getContribuyenteTmp().setCDepartamento(actualizarRucForm.getContribuyente().getTbMunicipio().getId().getCdepartamento());
        actualizarRucForm.getContribuyenteTmp().setCMunicipio(actualizarRucForm.getContribuyente().getTbMunicipio().getId().getCmunicipio());
        actualizarRucForm.getContribuyenteTmp().setCImportancia(actualizarRucForm.getContribuyente().getTbImportancia().getCimportancia());
        actualizarRucForm.getContribuyenteTmp().setCTipo(actualizarRucForm.getContribuyente().getTbTipoContrib().getId().getCtipo());
        actualizarRucForm.getContribuyenteTmp().setCAdmTrib(actualizarRucForm.getContribuyente().getTbAdmTrib().getCadmTrib());
        actualizarRucForm.getContribuyenteTmp().setCTermino(actualizarRucForm.getContribuyente().getTbTermino().getCtermino());
        actualizarRucForm.getContribuyenteTmp().setBActivo(Boolean.parseBoolean(actualizarRucForm.getContribuyente().getBactivo()));
        actualizarRucForm.getContribuyenteTmp().setBInteresFiscal(actualizarRucForm.getContribuyente().getBinteresFiscal());
        actualizarRucForm.getContribuyenteTmp().setBImportador(actualizarRucForm.getContribuyente().getBimportador());
        actualizarRucForm.getContribuyenteTmp().setCClase(actualizarRucForm.getContribuyente().getTbTipoContrib().getTbClaseContrib().getCclase());
        actualizarRucForm.getContribuyenteTmp().setFNacConst( actualizarRucForm.getContribuyente().getFnacConst());
        actualizarRucForm.getContribuyenteTmp().setFTermino(actualizarRucForm.getContribuyente().getFtermino());
        //actualizarRucForm.getContribuyenteTmp().setBAlerta(actualizarRucForm.getContribuyente().get);
        
    }
    
    
    /**********************************************
     * MANIPULACIÓN AJAX ACTIVIDAD ECONOMICA
     **********************************************/
    
    /**
     * Actualiza una actividad economica desde el frontend en el formulario popup de actividades
     * economicas. Se ejecuta cuando dan clic sobre el boton guardar.
     */
    @RequestMapping(value = "/actualizarActividadEconomica", method = RequestMethod.POST)
    public @ResponseBody String actualizarActividadEconomica( Model model, @ModelAttribute("datos_actualizados") String valor) {
        String[] valores = valor.split(",");
        String tipo = valores[0];
        String idCatalogoActividadesEco = valores[1];
        String orden = valores[2];
        
        ActualizarRucForm actualizarRucForm = (ActualizarRucForm) model.asMap().get("actualizarRucForm");  
        
       
        
        //Si el tipo es Nuevo es porque es un nuevo registro que agregar de lo contratio es una modificación.
        if(tipo.equals("N")){
            RcActEco nuevaActividad = new RcActEco();
            try{
                //Validando el orden (primera, segunda y tercera)
                for(RcActEco actividad : actualizarRucForm.getContribuyente().getRcActEcos()){
                    if(actividad.getOrden() == Long.parseLong(orden))
                        return "10,Actividad Económica repetida,";
                }
                //nuevaActividad.setIrcActEco(rcActEcoService.obtenerSiguienteLlave());
                nuevaActividad.setIrcActEco(rcActEcoService.getAllCount().longValue());
                nuevaActividad.setCusuario(usuario.getPrincipal().getNit());
                nuevaActividad.setOrden(Long.parseLong(orden));
                 for(TbActEco ac : actualizarRucForm.getActEco()){
                    if(ac.getCactEco().equals(idCatalogoActividadesEco))
                    nuevaActividad.setTbActEco(ac);    
                }
                actualizarRucForm.getContribuyente().getRcActEcos().add(nuevaActividad);
                return "00,Actividad economica guardada exitosamente,".concat(nuevaActividad.getIrcActEco().toString());
            }catch(Exception e){
                e.printStackTrace();
                return "11,Error al crear la actividad economica,";
            }
        }else{
             //Validando el orden (primera, segunda y tercera)
            for(RcActEco actividad : actualizarRucForm.getContribuyente().getRcActEcos()){
                if(actividad.getOrden() == Long.parseLong(orden) && actividad.getIrcActEco() != actualizarRucForm.getActividadEconomica().getIrcActEco())
                    return "10,Actividad Económica repetida,";
            }
            try{
                actualizarRucForm.getActividadEconomica().setOrden(Long.parseLong(orden));
                for(TbActEco ac : actualizarRucForm.getActEco()){
                    if(ac.getCactEco().equals(idCatalogoActividadesEco))
                    actualizarRucForm.getActividadEconomica().setTbActEco(ac);    
                }
                 for(RcActEco actividadEconomica : actualizarRucForm.getContribuyente().getRcActEcos()){
                     if(actividadEconomica.getIrcActEco() == actualizarRucForm.getActividadEconomica().getIrcActEco())
                         actividadEconomica = actualizarRucForm.getActividadEconomica();
                 }
                 return "00,Actividad economica guardada exitosamente,"+ actualizarRucForm.getActividadEconomica().getIrcActEco();
            }catch(Exception e){
                e.printStackTrace();
                return "12,Error al actualizar la actividad economica,";
            }
        }
         
     }
    
    /**
     *  Elimina la actividad economica cuando obtienen en el boton editar de la tabla.
     * @param v
     * @param model
     * @return
     */
    @RequestMapping(value = "/eliminarActividadEconomica/{v}")
    public @ResponseBody String eliminarActividadEconomica(@PathVariable String v, Model model) {
         ActualizarRucForm actualizarRucForm = (ActualizarRucForm) model.asMap().get("actualizarRucForm");
         try{
             for(RcActEco entidad : actualizarRucForm.getContribuyente().getRcActEcos()){
             if(entidad.getIrcActEco() == Integer.parseInt(v)){
                 actualizarRucForm.getContribuyente().getRcActEcos().remove(entidad);
                 break;
                }
            }
         }catch(Exception e){
             e.printStackTrace();
             return "16,Error al eliminar actividad economica";
         }
         return "00,Actividad Economica Eliminada Exitosametne";
     }
    
    /**
     *  Selecciona la actividad economica cuando obtienen en el boton editar de la tabla.
     * @param v
     * @param model
     * @return
     */
    @RequestMapping(value = "/seleccionarActividadEconomica/{v}")
    public @ResponseBody String seleccionarActividadEconomica(@PathVariable String v, Model model) {
         ActualizarRucForm actualizarRucForm = (ActualizarRucForm) model.asMap().get("actualizarRucForm");
         for(RcActEco entidad : actualizarRucForm.getContribuyente().getRcActEcos()){
             if(entidad.getIrcActEco() == Integer.parseInt(v)){
                 actualizarRucForm.setActividadEconomica(entidad);
             }
         }
         StringBuilder strB = new StringBuilder();
         
         strB.append(actualizarRucForm.getActividadEconomica().getIrcActEco()).append(",");
         strB.append(actualizarRucForm.getActividadEconomica().getTbActEco().getCactEco()).append(",");
         strB.append(actualizarRucForm.getActividadEconomica().getOrden());
          model.addAttribute("actualizarRucForm", actualizarRucForm);
          return strB.toString();
     }
    
    
    
    
    /*******************************************
     * MANIPULACIÓN AJAX SOCIOS
     *******************************************/
    /**
     *
     * @param v
     * @param model
     * @return
     */
    @RequestMapping(value = "/seleccionarSocio/{v}")
    public @ResponseBody String seleccionarSocio(@PathVariable String v, Model model) {
         ActualizarRucForm actualizarRucForm = (ActualizarRucForm) model.asMap().get("actualizarRucForm");
         for(RcSocio entidad : actualizarRucForm.getContribuyente().getRcSociosForNit()){
             if(entidad.getId().getNitsocio().equals(v)){
                 actualizarRucForm.setSocio(entidad);
             }
         }
         
         DateFormat formateadorFecha = new SimpleDateFormat("dd/MM/yyyy");
         StringBuilder strB = new StringBuilder();
         strB.append(actualizarRucForm.getSocio().getId().getNitsocio()).append(",");
         strB.append(actualizarRucForm.getSocio().getVporcPart()).append(",");
         strB.append(actualizarRucForm.getSocio().getFisocio()==null?
                        "":
                        formateadorFecha.format(actualizarRucForm.getSocio().getFisocio())
                 ).append(",");
         
         strB.append(actualizarRucForm.getSocio().getFfsocio()==null?
                     "":
                     formateadorFecha.format(actualizarRucForm.getSocio().getFfsocio())
                 ).append(",");
          model.addAttribute("actualizarRucForm", actualizarRucForm);
          return strB.toString();
     }
    
    @RequestMapping(value = "/actualizarSocio", method = RequestMethod.POST)
    public @ResponseBody String actualizarSocio( Model model, @ModelAttribute("datos_actualizados") String valor) {
        String[] valores = valor.split(",");
        String tipo = valores[0];
        String nitSocio = valores[1];
        String porcentaje = valores[2];
        String fechaInicio = valores[3];
        String fechaFin = "";
        try{
            fechaFin = valores[4];
        }catch(Exception ex){
            //Se captura cuando no hayan datos porque es permitido
        }
        
        DateFormat formatedorFecha = new SimpleDateFormat("dd/MM/yyyy");
        ActualizarRucForm actualizarRucForm = (ActualizarRucForm) model.asMap().get("actualizarRucForm");  
        if(tipo.equals("N")){
            RcSocio nueva= new RcSocio();
            try{
                for(RcSocio s : actualizarRucForm.getContribuyente().getRcSociosForNit()){
                    if(nitSocio.equals(s.getId().getNitsocio()))
                        return "Socio ya existenete,";
                }
                RcSocioId id = new RcSocioId(actualizarRucForm.getContribuyente().getNit(),nitSocio, "");
                nueva.setId(id);
                nueva.setCusuario(usuario.getPrincipal().getNit());
                nueva.setFfsocio(fechaFin.equals("")?null:formatedorFecha.parse(fechaFin));
                nueva.setFisocio(formatedorFecha.parse(fechaInicio));
                nueva.setVporcPart(Double.parseDouble(porcentaje));
                actualizarRucForm.getContribuyente().getRcSociosForNit().add(nueva);
                return "Socio creado exitosamente, "+nueva.getId().getNitsocio() ;
            }catch(Exception e){
                e.printStackTrace();
                return "Error al crear Socio, ";
            }
        }else{
            try{
                actualizarRucForm.getSocio().setCusuario(usuario.getPrincipal().getNit());
                actualizarRucForm.getSocio().setFisocio(formatedorFecha.parse(fechaInicio));
                actualizarRucForm.getSocio().setFfsocio(fechaFin.equals("")?null:formatedorFecha.parse(fechaFin));
                actualizarRucForm.getSocio().setVporcPart(Double.parseDouble(porcentaje));
                 for(RcSocio socio : actualizarRucForm.getContribuyente().getRcSociosForNit()){
                     if(socio.getId().getNitsocio().equals(actualizarRucForm.getSocio().getId().getNitsocio()))
                         socio = actualizarRucForm.getSocio();
                 }
            }catch(Exception e){
                e.printStackTrace();
                return "Error al actualizar la actividad economica,"+actualizarRucForm.getSocio().getId().getNitsocio();
            }
        }
         return "Actividad economica guardada exitosamente,"+actualizarRucForm.getSocio().getId().getNitsocio();
     }
    
    
    /***MANIPULACIÓN AJAX REPRESENTANTES***/
    
    @RequestMapping(value = "/seleccionarRepresentante/{v}")
    public @ResponseBody String seleccionarRepresentante(@PathVariable String v, Model model) {
         ActualizarRucForm actualizarRucForm = (ActualizarRucForm) model.asMap().get("actualizarRucForm");
         for(RcRepresentante entidad : actualizarRucForm.getContribuyente().getRcRepresentantesForNit()){
             if(entidad.getRcRucByNitRepresentante().getNit().equals(v)){
                 actualizarRucForm.setRepresentante(entidad);
             }
         }
         
         DateFormat formateadorFecha = new SimpleDateFormat("dd/MM/yyyy");
         StringBuilder strB = new StringBuilder();
         strB.append(actualizarRucForm.getRepresentante().getIrcRepresentante()).append(",");
         strB.append(actualizarRucForm.getRepresentante().getRcRucByNitRepresentante().getNit()).append(",");
         strB.append(actualizarRucForm.getRepresentante().getNdocAcredita()).append(",");
         strB.append(actualizarRucForm.getRepresentante().getCdocAcredita()).append(",");
         strB.append(actualizarRucForm.getRepresentante().getCdocIdentidad()).append(",");
         strB.append(actualizarRucForm.getRepresentante().getNdocIdentidad()).append(",");
         strB.append(actualizarRucForm.getRepresentante().getFirepresentante()==null?
                        "":
                        formateadorFecha.format(actualizarRucForm.getRepresentante().getFirepresentante())
                 ).append(",");
         
         strB.append(actualizarRucForm.getRepresentante().getFfrepresentante()==null?
                     "":
                     formateadorFecha.format(actualizarRucForm.getRepresentante().getFfrepresentante())
                 ).append(",");
          model.addAttribute("actualizarRucForm", actualizarRucForm);
          return strB.toString();
     }
    
    @RequestMapping(value = "/actualizarRepresentante", method = RequestMethod.POST)
    public @ResponseBody String actualizarRepresentante( Model model, @ModelAttribute("datos_actualizados") String valor) {
        String[] valores = valor.split(",");
        String tipo = valores[0];
        String nitSocio = valores[1];
        String porcentaje = valores[2];
        String fechaInicio = valores[3];
        String fechaFin = "";
        try{
            fechaFin = valores[4];
        }catch(Exception ex){
            //Se captura cuando no hayan datos porque es permitido
        }
        
        DateFormat formatedorFecha = new SimpleDateFormat("dd/MM/yyyy");
        ActualizarRucForm actualizarRucForm = (ActualizarRucForm) model.asMap().get("actualizarRucForm");  
        if(tipo.equals("N")){
            RcSocio nueva= new RcSocio();
            try{
                for(RcSocio s : actualizarRucForm.getContribuyente().getRcSociosForNit()){
                    if(nitSocio.equals(s.getId().getNitsocio()))
                        return "Socio ya existenete,";
                }
                RcSocioId id = new RcSocioId(actualizarRucForm.getContribuyente().getNit(),nitSocio, "");
                nueva.setId(id);
                nueva.setCusuario(usuario.getPrincipal().getNit());
                nueva.setFfsocio(fechaFin.equals("")?null:formatedorFecha.parse(fechaFin));
                nueva.setFisocio(formatedorFecha.parse(fechaInicio));
                nueva.setVporcPart(Double.parseDouble(porcentaje));
                actualizarRucForm.getContribuyente().getRcSociosForNit().add(nueva);
                return "Socio creado exitosamente, "+nueva.getId().getNitsocio() ;
            }catch(Exception e){
                e.printStackTrace();
                return "Error al crear Socio, ";
            }
        }else{
            try{
                actualizarRucForm.getSocio().setCusuario(usuario.getPrincipal().getNit());
                actualizarRucForm.getSocio().setFisocio(formatedorFecha.parse(fechaInicio));
                actualizarRucForm.getSocio().setFfsocio(fechaFin.equals("")?null:formatedorFecha.parse(fechaFin));
                actualizarRucForm.getSocio().setVporcPart(Double.parseDouble(porcentaje));
                 for(RcSocio socio : actualizarRucForm.getContribuyente().getRcSociosForNit()){
                     if(socio.getId().getNitsocio().equals(actualizarRucForm.getSocio().getId().getNitsocio()))
                         socio = actualizarRucForm.getSocio();
                 }
            }catch(Exception e){
                e.printStackTrace();
                return "Error al actualizar la actividad economica,"+actualizarRucForm.getSocio().getId().getNitsocio();
            }
        }
         return "Actividad economica guardada exitosamente,"+actualizarRucForm.getSocio().getId().getNitsocio();
     }
    
    

    
    /**
     * Busca en la BD el contribuyente que haya ingresado por validación de usuario
     * @return RcRuc retorna toda la información del contribuyente que ha ingresado
     */
    private RcRuc buscarContribuyentePorNitUsuario() {
        usuario = new HomeController();
        user = usuario.getPrincipal().getNit();
        //return rcRucService.findByNit(user);       
        return queryRucDao.obtenerRucPorNIT(user);
    }
    
    
    
   
    
    
    
   


   
}